package com.matt.controller.web;

import com.google.common.collect.Lists;
import com.matt.commons.dto.sso.StaffDTO;
import com.matt.commons.exception.BusinessException;
import com.matt.commons.model.StatusResponse;
import com.matt.commons.page.PagerQuery;
import com.matt.domain.LiveRoom;
import com.matt.domain.VideoCassetteRecorder;
import com.matt.foundation.constant.LiveRoomConstant;
import com.matt.foundation.dto.AreaSettingDTO;
import com.matt.foundation.model.ErrorCode;
import com.matt.foundation.model.MemVerificationCache;
import com.matt.service.LiveAddressService;
import com.matt.service.LiveRoomService;
import com.matt.service.UploadService;
import com.matt.service.VideoCassetteRecorderService;
import com.matt.service.remoteCall.SsoCallService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

import static com.matt.foundation.constant.RequestConstant.TICKET;
import static com.matt.foundation.model.ErrorCode.FILE_MAST_NOT_NULL;
import static com.matt.foundation.model.ErrorCode.SIGN_ERROR;

/**
 * *******************************
 * Created by Ron.
 * form com.matt
 * on 2017/7/14
 * *******************************
 */
@RestController
@RequestMapping("/web/live_room")
@Api(tags = "硬件 - 摄像头")
public class WebLiveRoomController {

    @Autowired
    private LiveRoomService liveRoomService;

    @Autowired
    private VideoCassetteRecorderService videoCassetteRecorderService;

    @Autowired
    SsoCallService ssoCallService;

    @Autowired
    private UploadService uploadService;

    @Autowired
    private LiveAddressService liveAddressService;

    @Autowired
    MemVerificationCache cache;

    private static final String LIVEROOM_SWITCH_KEY = "LIVEROOM_SWITCH_KEY";

    @ApiOperation(value = "获取微信摄像头列表开关状态",httpMethod = "GET")
    @RequestMapping(value = "/get_liveroom_switch",method = RequestMethod.GET)
    public StatusResponse getLiveRoomSwitch(@RequestHeader(TICKET) String ticket) {

        String areaId = cache.getAreaId(ticket);

        AreaSettingDTO s = ssoCallService.getAreaSetting(LIVEROOM_SWITCH_KEY, areaId);
        if(s != null) {
            return StatusResponse.success(Boolean.parseBoolean(s.getValue()));
        } else {
            return StatusResponse.success(true + "");
        }
    }

    @ApiOperation(value = "设置微信摄像头列表开关状态",httpMethod = "POST")
    @RequestMapping(value = "/set_liveroom_switch",method = RequestMethod.POST)
    public StatusResponse getLiveRoomSwitch(@RequestHeader(TICKET) String ticket, boolean enabled) {

        String areaId = cache.getAreaId(ticket);

        boolean ret = ssoCallService.addAreaSetting(LIVEROOM_SWITCH_KEY, enabled + "", "微信内是否启用幼儿园摄像头开关", "", areaId);

        return StatusResponse.success();
    }

    @ApiOperation(value = "设置园区萤石云配置",httpMethod = "POST")
    @RequestMapping(value = "/set_yinshi_config",method = RequestMethod.POST)
    public StatusResponse setYinShiConfig(@RequestHeader(TICKET) String ticket, String ysAppKey, String ysAppSecret ) {
        String areaId = cache.getAreaId(ticket);
        if(StringUtils.isNotEmpty(ysAppKey)){
            Boolean ret = ssoCallService.addAreaSetting("ysKey", ysAppKey, "园区修改的萤石云AppKey", "", areaId);
            if(!ret){
                return StatusResponse.error(ErrorCode.SSO_CALL_ERROR, "修改配置失败1");
            }
        }

        if(StringUtils.isNotEmpty(ysAppSecret)){
            Boolean ret = ssoCallService.addAreaSetting("ysSecret", ysAppSecret, "园区修改的萤石云AppSecret", "", areaId);
            if(!ret){
                return StatusResponse.error(ErrorCode.SSO_CALL_ERROR, "修改配置失败2");
            }
        }

        return StatusResponse.success();
    }

    @ApiOperation(value = "获取园区萤石云配置",httpMethod = "GET")
    @RequestMapping(value = "/get_yinshi_config",method = RequestMethod.GET)
    public StatusResponse setLiveRoomSwitch(@RequestHeader(TICKET) String ticket) {
        String areaId = cache.getAreaId(ticket);

        AreaSettingDTO yk = ssoCallService.getAreaSetting("ysKey", areaId);
        AreaSettingDTO ys = ssoCallService.getAreaSetting("ysSecret", areaId);

        Map<String, String> ret = new HashMap();
        if(yk != null && ys != null){
            ret.put(yk.getKey(), yk.getValue());
            ret.put(ys.getKey(), ys.getValue());
        }

        return StatusResponse.success(ret);
    }

    @ApiOperation(value = "WEB 本园区摄像头",httpMethod = "POST")
    @RequestMapping("/cameraList")
    public StatusResponse getCameraList(@RequestHeader(TICKET) String ticket, PagerQuery pagerQuery) {
        String areaId = cache.getAreaId(ticket);
        Page page = liveRoomService.getActiveRoomByAreaPage(areaId, pagerQuery);
        return StatusResponse.success(page);
    }

    @ApiOperation(value = "本教学区域可选摄像头",httpMethod = "POST")
    @RequestMapping("/list_by_teach_area")
    public StatusResponse listByTeachArea(@RequestHeader(TICKET) String ticket, String teachAreaId) {
        String areaId = cache.getAreaId(ticket);
        List<LiveRoom> roomList = liveRoomService.getActiveRoomByAreaAndNoChoosen(areaId, teachAreaId);
        return StatusResponse.success(roomList);
    }

    @ApiOperation(value = "WEB 根据园区id查询摄像头",httpMethod = "POST")
    @RequestMapping("/list_by_area")
    public StatusResponse cameralist(@RequestHeader(TICKET) String ticket) {
        String areaId = cache.getAreaId(ticket);
        List<LiveRoom> roomList = liveRoomService.getRoomByArea(areaId);
        return StatusResponse.success(roomList);
    }

    @ApiOperation(value = "根据摄像头ID获取明细",httpMethod = "POST")
    @RequestMapping("/detail")
    public StatusResponse detail(@RequestHeader(TICKET) String ticket, String roomId) {
        String areaId = cache.getAreaId(ticket);
        LiveRoom room = liveRoomService.getByIdInArea(roomId, areaId);

        return StatusResponse.success(room);
    }

    @ApiOperation(value = "添加摄像头",httpMethod = "POST")
    @RequestMapping("/add")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "id", value = "摄像头 id，不传表示新建，传就修改", required = false, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "teachingAreaId", value = "教学区域id", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "url", value = "标清URL", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "HDUrl", value = "高清URL", required = false, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "thumbUrl", value = "封面URL", required = false, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "yingshiId", value = "萤石云id， type=1时需要", required = false, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "name", value = "摄像头名字", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "type", value = "摄像头类型, 1是萤石云（需要实时计算播放地址），2是手动添加摄像头", required = true, dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "isActive", value = "家长是否可见", required = false, dataType = "boolean"),
    })
    public StatusResponse add(@RequestHeader(TICKET) String ticket,
                              String teachingAreaId,
                              String id,
                              @RequestParam String url,
                              @RequestParam String HDUrl,
                              String thumbUrl,
                              String yingshiId,
                              @RequestParam String name, Integer type,
                              @RequestParam(defaultValue = "true") Boolean isActive) {
        String areaId = cache.getAreaId(ticket);

        LiveRoom room = null;
        if (StringUtils.isBlank(id)){
            room = liveRoomService.add(url, HDUrl, thumbUrl, yingshiId, name, type, areaId, teachingAreaId, isActive);
        }else{
            room = liveRoomService.modify(id, url, HDUrl, thumbUrl, yingshiId, name, type, areaId, teachingAreaId, isActive);
        }

        return StatusResponse.success(room);
    }

    @ApiOperation(value = "删除一个自添加摄像头",httpMethod = "DELETE")
    @RequestMapping(value = "/{liveRoomId}",method = RequestMethod.DELETE)
    public StatusResponse deleteCamera(@RequestHeader(TICKET) String ticket, @PathVariable("liveRoomId") String liveRoomId) {
        StaffDTO staff = ssoCallService.getStaffDTO(ticket);

        LiveRoom ret = liveRoomService.delete(staff.getAreaId(), staff.getId(), liveRoomId);

        return StatusResponse.success(ret);
    }

    @ApiOperation(value = "WEB 修改园区摄像头信息",httpMethod = "POST")
    @RequestMapping("/modify_name")
    public StatusResponse modifyName(@RequestHeader(TICKET) String ticket, String roomId, String name, String time) {

        List<String> times = Lists.newArrayList();
        try {
            if (StringUtils.isNotBlank(time)) {
                if (time.indexOf(",") != -1) {
                    String[] split = time.split(",");
                    times = Arrays.asList(split);
                } else {
                    times.add(time);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(ErrorCode.SIGN_ERROR, "时间格式异常");
        }

        String areaId = cache.getAreaId(ticket);

        LiveRoom room = liveRoomService.modifyName(roomId, name, times, areaId);
        if (room != null)
            return StatusResponse.success(room);
        else
            return StatusResponse.error(SIGN_ERROR, "更新失败，设备序列号或通道号不存在，请更新摄像头状态！");
    }

    @ApiOperation(value = "更新摄像头封面",httpMethod = "POST")
    @RequestMapping(value = "/update_camera_thumbnail" ,method = RequestMethod.POST)
    public StatusResponse teacherUploadImg(@RequestHeader(TICKET) String ticket,
                                           String cameraId, MultipartFile file) {
        if (Objects.isNull(file))
            return StatusResponse.error(FILE_MAST_NOT_NULL,"文件不能为空");

        String areaId = cache.getAreaId(ticket);

        String url = uploadService.uploadLiveRoomImg(cameraId, file);
        LiveRoom result = liveRoomService.updateThumbUrlById(areaId, cameraId, url);

        return StatusResponse.success(result);
    }

    @ApiOperation(value = "WEB 修改园区摄像头状态",httpMethod = "POST")
    @RequestMapping("/modify_status")
    public StatusResponse modify(@RequestHeader(TICKET) String ticket, String roomId, Boolean active) {
        String areaId = cache.getAreaId(ticket);
        LiveRoom room = liveRoomService.modifyStatus(roomId, active, areaId);
        return StatusResponse.success(room);
    }


    @ApiOperation("获取播放器地址")
    @RequestMapping(value = "/playerURL", method = RequestMethod.GET)
    public StatusResponse playerURL(@RequestHeader(TICKET) String ticket,  String roomId){

        String areaId = cache.getAreaId(ticket);

        LiveRoom liveRoom = liveRoomService.getByIdInArea(roomId, areaId);
        if (liveRoom == null){
            throw new BusinessException(ErrorCode.MATERIAL_NOT_EXIST, "摄像头不存在");
        }

        String url = liveRoomService.getLiveRoomHLSAddress(liveRoom);

        //TODO: 开启推流
        liveRoomService.openLive(liveRoom);

        return StatusResponse.success(url);
    }


    @ApiOperation(value = "获取录像机列表",httpMethod = "POST")
    @RequestMapping("/vcr/list")
    public StatusResponse vcrList(@RequestHeader(TICKET) String ticket) {
        String areaId = cache.getAreaId(ticket);
        List<VideoCassetteRecorder> vcr = videoCassetteRecorderService.findByArea(areaId);
        return StatusResponse.success(vcr);
    }

    @ApiOperation(value = "添加录像机",httpMethod = "POST")
    @RequestMapping("/vcr/add")
    public StatusResponse vcrAdd(@RequestHeader(TICKET) String ticket, String name, String serialNumber,
                                 @RequestParam(required = true, defaultValue = "2") Integer liveWay) {
        if (liveWay != LiveRoomConstant.LIVEWAY_EZOPEN && liveWay != LiveRoomConstant.LIVEWAY_RTMP)
            throw new BusinessException(ErrorCode.SIGN_ERROR, "参数有误！");

        String areaId = cache.getAreaId(ticket);

        VideoCassetteRecorder vcr = videoCassetteRecorderService.add(areaId, name, serialNumber, liveWay);

        return StatusResponse.success(vcr);
    }

    @ApiOperation(value = "删除录像机",httpMethod = "DELETE")
    @RequestMapping(value = "/vcr/{vcrId}", method = RequestMethod.DELETE)
    public StatusResponse vcrDelete(@RequestHeader(TICKET) String ticket,@PathVariable String vcrId) {
        String areaId = cache.getAreaId(ticket);

        Boolean ret = videoCassetteRecorderService.delete(areaId, vcrId);

        return StatusResponse.success(ret);
    }

    @ApiOperation(value = "修改录像机",httpMethod = "POST")
    @RequestMapping("/vcr/modify")
    public StatusResponse vcrModify(@RequestHeader(TICKET) String ticket, String id, String name, String serialNumber,
                                    @RequestParam(required = true, defaultValue = "2") Integer liveWay) {
        if (liveWay != LiveRoomConstant.LIVEWAY_EZOPEN && liveWay != LiveRoomConstant.LIVEWAY_RTMP)
            throw new BusinessException(ErrorCode.SIGN_ERROR, "参数有误！");

        String areaId = cache.getAreaId(ticket);

        VideoCassetteRecorder vcr = videoCassetteRecorderService.modify(id, name, serialNumber, liveWay,areaId);

        return StatusResponse.success(vcr);
    }

//    @ApiOperation(value = "刷新录像机状态",httpMethod = "POST")
//    @RequestMapping("/vcr/refresh")
//    public StatusResponse vcrRefresh() {
//        videoCassetteRecorderService.refreshAll();
//        return StatusResponse.success();
//    }

    /**
     * @param deviceSerial
     * @return 刷新录像机下所有摄像头
     */
    @ApiOperation(value = "刷新单个录像机下摄像头状态",httpMethod = "POST")
    @RequestMapping("/vcr/refreshSingle")
    public StatusResponse refreshVCRSingle(@RequestHeader(TICKET) String ticket,
                                           @RequestParam(required = true) String deviceSerial ) {
        String areaId = cache.getAreaId(ticket);
        return StatusResponse.success(videoCassetteRecorderService.refreshVCRSingle(areaId, deviceSerial));
    }

    /**
     * @param deviceSerial
     * @return 取录像机下所有摄像头
     */
    @ApiOperation(value = "取录像机下所有摄像头",httpMethod = "POST")
    @RequestMapping("/vcr/getCamera")
    public StatusResponse getCameraByAreaIdAndSerial(@RequestHeader(TICKET) String ticket, String deviceSerial) {
        String areaId = cache.getAreaId(ticket);
        return StatusResponse.success(videoCassetteRecorderService.getCameraByAreaIdAndSerial(areaId, deviceSerial));
    }

    /**
     * @param deviceSerial
     * @param channelNo
     * @return 开通或关闭直播
     */
    @ApiOperation(value = "开通或关闭直播",httpMethod = "POST")
    @RequestMapping("/vcr/openOrCloseLive")
    public StatusResponse openLive(@RequestHeader(TICKET) String ticket, String deviceSerial, String channelNo, Integer type) {

        String areaId = cache.getAreaId(ticket);

        switch (type) {
            case 1:
                return StatusResponse.success(videoCassetteRecorderService.openLive(areaId, deviceSerial, channelNo));
            case 2:
                return StatusResponse.success(videoCassetteRecorderService.closeLive(areaId, deviceSerial, channelNo));
        }
        return StatusResponse.error("920000", "参数有误");
    }

    @ApiOperation(value = "生成推流和播放地址",httpMethod = "POST")
    @RequestMapping("/generate_live_url")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "stage", value = "存储桶，例如 2， 或者 3", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "areaName", value = "园区简称", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "count", value = "生成多少个", required = true, dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "suffix", value = "后缀", required = true, dataType = "string"),
    })
    public StatusResponse openLive(@RequestHeader(TICKET) String ticket, String stage, String areaName, String suffix, int count) {
        return StatusResponse.success(liveAddressService.generatePushAddress(stage, areaName, suffix, count));
    }

    @ApiOperation(value = "生成外部合作伙伴的推流和播放地址",httpMethod = "POST")
    @RequestMapping("/generate_biz_live_url")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "stage", value = "存储桶，例如 1", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "areaName", value = "园区简称", required = true, dataType = "string"),
            @ApiImplicitParam(paramType = "query", name = "count", value = "生成多少个", required = true, dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "suffix", value = "后缀", required = true, dataType = "string"),
    })
    public StatusResponse generateBizLiveUrl(@RequestHeader(TICKET) String ticket, String stage, String areaName, String suffix, int count) {
        return StatusResponse.success(liveAddressService.generateBizPushAddress(stage, areaName, suffix, count));
    }

    @ApiOperation(value = "更新 - 使用时间",httpMethod = "POST")
    @RequestMapping("/update_date")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "liveRoomId", value = "摄像头ID", required = true, dataType = "string"),
    })
    public StatusResponse updateDate(@RequestHeader(TICKET) String ticket, String liveRoomId) {
        liveRoomService.updateDate(liveRoomId);
        return StatusResponse.success();
    }

    @ApiOperation(value = "打开 - 摄像头",httpMethod = "POST")
    @RequestMapping("/open_live")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "liveRoomId", value = "摄像头ID", required = true, dataType = "string"),
    })
    public StatusResponse open_live(@RequestHeader(TICKET) String ticket, String liveRoomId)  {
//        String areaId = cache.getAreaId(ticket);
//        return StatusResponse.success(liveRoomService.openLive(areaId, liveRoomId));
        return StatusResponse.success(1);
    }

    @ApiOperation(value = "关闭 - 摄像头",httpMethod = "POST")
    @RequestMapping("/close_live")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "liveRoomId", value = "摄像头ID", required = true, dataType = "string"),
    })
    public StatusResponse close_live(@RequestHeader(TICKET) String ticket, String liveRoomId) {
//        liveRoomService.closeLive(liveRoomId);
//        return StatusResponse.success();
        return StatusResponse.success(1);
    }
}
